package yxy.game.pm2.module.kow;

import java.util.HashMap;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;

import yxy.apple.util.redisson.RedisException;
import yxy.game.pm2.bean.module.RedisLock;
import yxy.game.pm2.bean.module.WorldModule;
import yxy.game.pm2.module.kow.KowHandle.KowFinalCode;
import yxy.game.pm2.module.kow.KowHandle.KowStepEnum;

/** 天下第一 */
public class KowModule extends WorldModule {
	// bean===========================================================================

	private String code;// 比赛代号

	private int round;// 小组赛回合
	private boolean running;// 比赛进行中
	private HashMap<KowFinalCode, KowFinal> finals = new HashMap<>();

	private DateTime startTime;
	private KowStepEnum state;
	private HashMap<KowStepEnum, DateTime> stateTimes = new HashMap<>();

	private int areaGroupId; //战区id

	public int getAreaGroupId() {
		return areaGroupId;
	}

	public void setAreaGroupId(int areaGroupId) {
		this.areaGroupId = areaGroupId;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public KowStepEnum getState() {
		return state;
	}

	public void setState(KowStepEnum state) {
		this.state = state;
	}

	public HashMap<KowFinalCode, KowFinal> getFinals() {
		return finals;
	}

	public void setFinals(HashMap<KowFinalCode, KowFinal> finals) {
		this.finals = finals;
	}

	public int getRound() {
		return round;
	}

	public void setRound(int round) {
		this.round = round;
	}

	public boolean isRunning() {
		return running;
	}

	public void setRunning(boolean running) {
		this.running = running;
	}

	public DateTime getStartTime() {
		return startTime;
	}

	public void setStartTime(DateTime startTime) {
		this.startTime = startTime;
	}

	public HashMap<KowStepEnum, DateTime> getStateTimes() {
		return stateTimes;
	}

	public void setStateTimes(HashMap<KowStepEnum, DateTime> stateTimes) {
		this.stateTimes = stateTimes;
	}

	// func===========================================================================
	static public String code(DateTime time) {
		DateTime firstday = time.withDayOfWeek(1).withTimeAtStartOfDay();// 赛季第一天
		String code = firstday.toString(DateTimeFormat.forPattern("yyyyMMdd"));
		// XXX 短时测试
//		String code = time.toString(DateTimeFormat.forPattern("yyyyMMddmmss"));
		return code;
	}

	public void update() {

	}

	public DateTime stateTime() {
		return getStateTimes().get(getState());
	}

	public void addFinal(KowFinal kowFinal) {
		getFinals().put(kowFinal.getFinalCode(), kowFinal);
	}

	public void resetState(DateTime time) {

		DateTime startTime = time.withDayOfWeek(1).withTimeAtStartOfDay();// 赛季第一天
		//if (time.getDayOfWeek() > 1 || time.getHourOfDay() >= 12) {
		if (time.getDayOfWeek() > 4) { //周四前都可以开启当周的赛事，超过周四，则下一周开启
			startTime = startTime.plusWeeks(1);
		}

		getStateTimes().clear();

		getStateTimes().put(KowStepEnum.STEP_PRE, startTime.plusHours(12));
		getStateTimes().put(KowStepEnum.STEP_GROUP_1, startTime.plusHours(18));
		getStateTimes().put(KowStepEnum.STEP_GROUP_1_SET, startTime.plusHours(22));
		getStateTimes().put(KowStepEnum.STEP_GROUP_2, startTime.plusDays(1).plusHours(18));
		getStateTimes().put(KowStepEnum.STEP_GROUP_2_SET, startTime.plusDays(1).plusHours(22));
		getStateTimes().put(KowStepEnum.STEP_GROUP_3, startTime.plusDays(2).plusHours(18));
		getStateTimes().put(KowStepEnum.STEP_GROUP_3_SET, startTime.plusDays(2).plusHours(22));
		getStateTimes().put(KowStepEnum.STEP_GROUP_4, startTime.plusDays(3).plusHours(18));
		getStateTimes().put(KowStepEnum.STEP_GROUP_4_SET, startTime.plusDays(3).plusHours(22));
		getStateTimes().put(KowStepEnum.STEP_QUARTER, startTime.plusDays(4).plusHours(18));
		getStateTimes().put(KowStepEnum.STEP_SEMI, startTime.plusDays(5).plusHours(18));
		getStateTimes().put(KowStepEnum.STEP_FINAL, startTime.plusDays(6).plusHours(18));
		getStateTimes().put(KowStepEnum.STEP_OFFSEASON, startTime.plusWeeks(1));

		setState(KowStepEnum.STEP_PRE);
		setRunning(false);
		setStartTime(startTime);
		setCode(code(startTime));
	}

	// XXX 短时测试
//	public void resetState(DateTime time) {
//		DateTime startTime = time.withTimeAtStartOfDay();// 赛季第一天
//		if (getStateTimes().containsKey(KowStepEnum.STEP_OFFSEASON)) {
//			startTime = startTime.plusHours(time.getHourOfDay()).plusMinutes(time.getMinuteOfHour() - (time.getMinuteOfHour() % 15));
//		}
//
//		getStateTimes().clear();
//
//		getStateTimes().put(KowStepEnum.STEP_PRE, startTime.plusMinutes(1));
//		getStateTimes().put(KowStepEnum.STEP_GROUP_1, startTime.plusMinutes(2));
//		getStateTimes().put(KowStepEnum.STEP_GROUP_1_SET, startTime.plusMinutes(3));
//		getStateTimes().put(KowStepEnum.STEP_GROUP_2, startTime.plusMinutes(4));
//		getStateTimes().put(KowStepEnum.STEP_GROUP_2_SET, startTime.plusMinutes(5));
//		getStateTimes().put(KowStepEnum.STEP_GROUP_3, startTime.plusMinutes(6));
//		getStateTimes().put(KowStepEnum.STEP_GROUP_3_SET, startTime.plusMinutes(7));
//		getStateTimes().put(KowStepEnum.STEP_GROUP_4, startTime.plusMinutes(8));
//		getStateTimes().put(KowStepEnum.STEP_GROUP_4_SET, startTime.plusMinutes(9));
//		getStateTimes().put(KowStepEnum.STEP_QUARTER, startTime.plusMinutes(10));
//		getStateTimes().put(KowStepEnum.STEP_SEMI, startTime.plusMinutes(11));
//		getStateTimes().put(KowStepEnum.STEP_FINAL, startTime.plusMinutes(12));
//		getStateTimes().put(KowStepEnum.STEP_OFFSEASON, startTime.plusMinutes(15));
//
//		setState(KowStepEnum.STEP_PRE);
//		setRunning(false);
//		setStartTime(startTime);
//		setCode(code(startTime));
//	}

	// redis==========================================================================

	static private String key(int areaGroupId) {
		return key(areaGroupId, "KOW:INFO");
	}

	public void set() {
		try {
			setv(key(getAreaGroupId()), this);
		} catch (RedisException e) {
			e.printStackTrace();
		}
	}

//	public static KowModule get(String playerCode) {
//		AreaBean area = area(playerCode);
//		return get(area.getAreaId());
//	}

	public static KowModule get(int areaGroupId) {
		try {
			//WORLD:*:MODULE:KOW:INFO
			KowModule module = getv(key(areaGroupId));
			if (module == null) {
				module = create(areaGroupId);
			}
			module.update();
			return module;
		} catch (RedisException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static KowModule create(int areaGroupId) {
		KowModule module = new KowModule();
		module.setAreaGroupId(areaGroupId);
		module.resetState(DateTime.now());
		module.set();
		return module;
	}
	// lock==========================================================================

	@Override
	public String lockKey() {
		return String.format("lock:%s", key(getAreaGroupId()));
	}

	@Override
	public boolean tryLock() throws InterruptedException {
		return super.tryLock();
	}

	public static RedisLock lock(int areaGroupId) {
		return getLock(String.format("lock:%s", key(areaGroupId)));
	}

}
